package cn.git.controller;

import cn.hutool.core.util.StrUtil;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;

/**
 * 控制器用于远程执行shell脚本。
 *
 * @program: bank-credit-sy
 * @author: lixuchun
 * @create: 2024-05-03
 */
@RestController
@RequestMapping("/shell")
public class ExecShellController {

    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(ExecShellController.class);

    /**
     * 测试远程执行shell脚本的方法。
     *
     * @return 返回执行结果的信息
     */
    @RequestMapping("/exec")
    public String test() {
        // 定义远程服务器的登录信息,用户名称
        String user = "root";
        // 密码
        String password = "101022li";
        // 地址
        String host = "192.168.138.129";
        int port = 22; // 端口
        try {
            JSch jsch = new JSch();
            Session session = jsch.getSession(user, host, port);
            session.setPassword(password);

            // 设置配置避免首次连接时的确认提示
            session.setConfig("StrictHostKeyChecking", "no");
            // 建立连接
            session.connect();

            // 准备执行的shell命令
            String execCommand = "sh /root/shell/test.sh";
            Channel channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(execCommand);
            // 不向远程服务器发送输入
            channel.setInputStream(null);
            // 将错误输出流重定向到标准错误输出
            ((ChannelExec) channel).setErrStream(System.err);
            // 连接通道，设置超时时间为1s,单位为毫秒
            channel.connect(1000);

            // 读取shell脚本的标准输出
            StringBuilder result = new StringBuilder(StrUtil.EMPTY);
            try (InputStream in = channel.getInputStream()) {
                byte[] buffer = new byte[1024]; // 缓冲区大小
                int readCount;
                // 循环读取直到没有更多数据
                while ((readCount = in.read(buffer)) > 0) {
                    result.append(new String(buffer, 0, readCount));
                }
            }

            // 获取结果信息
            logger.info("获取Result: {} ", result);

            // 断开连接
            channel.disconnect();
            session.disconnect();
        } catch (Exception e) {
            // 异常处理
            logger.error("执行 shell 脚本错误: {}", e.getMessage(), e);
            return "exec failed";
        }
        // 返回执行成功信息
        return "exec ok";
    }

}
